/** 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.free.i.naming;

import javax.naming.NamingException;
import javax.naming.Reference;

/** 
 * Enhanced class factory.
 * @author  stefano
 */
public class JndiClassFactory {

    /**
     * Singleton private instance accessor
     */
    private JndiClassFactory() {
        super();
    }

    /**
     * Create the class for name instance
     * @param className
     * @return a generic class to cast
     * @throws NamingException
     */
    public static final Object classForName(String className) throws NamingException {
        Object instance = null;
        try{
            instance = Class.forName(className, false, Thread.currentThread().getContextClassLoader()).newInstance();
        }catch(ClassNotFoundException cnfExc) {
               throw (new NamingException("Identity class [" + className + "] not found: " + cnfExc.getMessage()));
        }catch(SecurityException sExc) {
               throw (new NamingException("Security exception getting class [" + className + "] loader: " + sExc.getMessage()));
        }catch(LinkageError lExc) {
               throw (new NamingException("Bad class [" + className + "] (dependencies are broken or changed after last compilation: " + lExc.getMessage()));
        }catch(IllegalAccessException iaExc){
               throw (new NamingException("Name indicates a class [" + className + "] that is not accessible: " + iaExc.getMessage()));
        }catch(InstantiationException iExc){
               throw (new NamingException("Name indicates a class [" + className + "] that maybe cannot be instantiated: " + iExc.getMessage()));
        }
        return instance;
    }
    
    /**
     * Create the class for name instance
     * @param lookupName is the name to look up
     * @return a generic class to cast
     * @throws NamingException
     */
    public static final Object classForJndiName(String lookupName) throws NamingException {
        
        if( (lookupName == null) ||
            (lookupName.trim().equals("")) ){
             throw (new NamingException("Lookup up name is invalid: [" + lookupName + "]"));
        }
        
        Reference reference =  (Reference) CachedNamingProviderProxy.getInstance().lookup(lookupName);
        Object instance = JndiClassFactory.classForName(reference.getClassName());

        return instance;
   }
    
    /**
     * Create the class for name instance
     * @param className
     * @return a generic class name in the java format
     * @throws IdentityLookupException
     */
//    public static final String classNameForJndiName(String lookupName) throws IdentityLookupException {
//        
//        if( (lookupName == null) ||
//            (lookupName.trim().equals("")) ){
//             throw (new IdentityLookupException("Lookup up name is invalid: [" + lookupName + "]"));
//        }
//        
//        Reference reference =  (Reference) CachedNamingProviderProxy.getInstance().lookup(lookupName);
//        String classPhysicalName = reference.getClassName();
//
//        return classPhysicalName;
//   }
    
}
